home *** CD-ROM | disk | FTP | other *** search
-
- #include "lib_init.h"
- #include "lib_debug.h"
- #include <render/render.h>
- #include <proto/utility.h>
- #include <proto/exec.h>
-
-
- /**************************************************************************
- **
- ** createhistogram
- */
-
- LIBAPI RNDHISTO *CreateHistogramA(struct TagItem *tags)
- {
- APTR rmh;
- RNDHISTO *h;
- UWORD type;
-
- type = (UWORD) GetTagData(RND_HSType, HSTYPE_15BIT_TURBO, tags);
- switch (type)
- {
- case HSTYPE_12BIT:
- case HSTYPE_15BIT:
- case HSTYPE_18BIT:
- case HSTYPE_21BIT:
- case HSTYPE_24BIT:
- break;
-
- case HSTYPE_12BIT_TURBO:
- case HSTYPE_15BIT_TURBO:
- case HSTYPE_18BIT_TURBO:
- type &= HSTYPE_MASK; /* turbo currently not supported */
- break;
-
- default:
- return NULL;
- }
-
- rmh = (APTR) GetTagData(RND_RMHandler, NULL, tags);
- h = AllocRenderVecClear(rmh, sizeof(RNDHISTO));
- if (h)
- {
- ULONG mask;
- InitSemaphore(&h->lock);
- h->type = type;
- h->rmh = rmh;
- h->bitspergun = type & HSTYPE_MASK;
- mask = (0xff << (8 - h->bitspergun)) & 0xff;
- h->rgbmask = (mask << 16) | (mask << 8) | mask;
- }
- return h;
- }
-
-
- /**************************************************************************
- **
- ** deletehistogram
- */
-
- LIBAPI void DeleteHistogram(RNDHISTO *h)
- {
- if (h)
- {
- struct RNDTreeMemBlock *node, *nextnode;
-
- node = h->memlist;
- while (node)
- {
- nextnode = node->next;
- FreeRenderMem(h->rmh, node, sizeof(struct RNDTreeMemBlock));
- node = nextnode;
- }
-
- FreeRenderVec((ULONG *) h);
- }
- }
-
-
- /**************************************************************************
- **
- ** queryhistogram
- */
-
- LIBAPI ULONG QueryHistogram(RNDHISTO *h, Tag tag)
- {
- ULONG result = 0xffffffff;
- switch (tag)
- {
- case RND_NumColors:
- result = h->numcolors;
- break;
- case RND_NumPixels:
- result = h->numpixels;
- break;
- case RND_RMHandler:
- result = (ULONG) h->rmh;
- break;
- case RND_HSType:
- result = (ULONG) h->type;
- break;
- }
- return result;
- }
-
-
-
- /*
- ** tree histogram
- */
-
- static struct RNDTreeNode *alloctreenode(RNDHISTO *h)
- {
- struct RNDTreeMemBlock *mn = h->memlist;
-
- if (mn)
- {
- if (mn->free)
- {
- return mn->nodes + --mn->free;
- }
- }
-
- mn = AllocRenderMem(h->rmh, sizeof(struct RNDTreeMemBlock));
- if (mn)
- {
- mn->next = h->memlist;
- h->memlist = mn;
- mn->free = RNDTREEMEMBLOCK_NUMNODES - 1;
- return mn->nodes + RNDTREEMEMBLOCK_NUMNODES - 1;
- }
-
- return NULL;
- }
-
-
- static LONG addrgb_tree(RNDHISTO *h, ULONG rgb, ULONG count)
- {
- struct RNDTreeNode **nodeptr = &h->root;
- struct RNDTreeNode *node;
-
- ULONG rgbmask = h->rgbmask;
- ULONG chkmask = 0x800000;
-
- rgb &= rgbmask;
-
- while (node = *nodeptr)
- {
- if (node->entry.rgb == rgb)
- {
- node->entry.count += count;
- h->numpixels += count;
- return ADDH_SUCCESS;
- }
-
- while (!(chkmask & rgbmask)) chkmask >>= 1;
-
- if (rgb & chkmask)
- {
- nodeptr = &node->left;
- }
- else
- {
- nodeptr = &node->right;
- }
-
- chkmask >>= 1;
- }
-
- node = alloctreenode(h);
- if (node)
- {
- *nodeptr = node;
- node->left = NULL;
- node->right = NULL;
- node->entry.rgb = rgb;
- node->entry.count = count;
- h->numpixels += count;
- h->numcolors++;
- return ADDH_SUCCESS;
- }
-
- return ADDH_NOT_ENOUGH_MEMORY;
- }
-
-
- /**************************************************************************
- **
- ** addrgb
- */
-
- LIBAPI ULONG AddRGB(RNDHISTO *h, ULONG rgb, ULONG count)
- {
- ULONG result = ADDH_NO_DATA;
- if (h && count)
- {
- ObtainSemaphore(&h->lock);
- result = addrgb_tree(h, rgb, count);
- ReleaseSemaphore(&h->lock);
- }
- return result;
- }
-
- /**************************************************************************
- **
- ** addrgbimage
- */
-
- LIBAPI ULONG AddRGBImageA(RNDHISTO *h, ULONG *rgb, UWORD width, UWORD height, struct TagItem *tags)
- {
- ULONG result = ADDH_NO_DATA;
- if (h && rgb && width && height)
- {
- struct RND_ProgressMessage progmsg;
- struct Hook *proghook = (struct Hook *) GetTagData(RND_ProgressHook, NULL, tags);
- UWORD totw = (UWORD) GetTagData(RND_SourceWidth, width, tags);
- UWORD y, x;
-
- progmsg.RND_PMsg_type = PMSGTYPE_LINES_ADDED;
- progmsg.RND_PMsg_total = height;
-
- ObtainSemaphore(&h->lock);
-
- for (y = 0; y < height; ++y)
- {
- for (x = 0; x < width; ++x)
- {
- result = addrgb_tree(h, *rgb++, 1);
- if (result != ADDH_SUCCESS) goto fail;
- }
-
- if (proghook)
- {
- progmsg.RND_PMsg_count = y;
- if (!CallHookPkt(proghook, h, &progmsg))
- {
- result = ADDH_CALLBACK_ABORTED;
- goto fail;
- }
- }
-
- rgb += totw - width;
- }
- fail:
- ReleaseSemaphore(&h->lock);
- }
- return result;
- }
-
-
- /**************************************************************************
- **
- ** addchunkyimage
- */
-
- LIBAPI ULONG AddChunkyImageA(RNDHISTO *h, UBYTE *chunky,
- UWORD width, UWORD height, RNDPAL *p, struct TagItem *tags)
- {
- ULONG result = ADDH_NO_DATA;
- if (h && p && chunky && width && height)
- {
- struct RND_ProgressMessage progmsg;
- struct Hook *proghook = (struct Hook *) GetTagData(RND_ProgressHook, NULL, tags);
- UWORD totw = (UWORD) GetTagData(RND_SourceWidth, width, tags);
- UWORD y, x;
-
- progmsg.RND_PMsg_type = PMSGTYPE_LINES_ADDED;
- progmsg.RND_PMsg_total = height;
-
- ObtainSemaphore(&h->lock);
-
- for (y = 0; y < height; ++y)
- {
- for (x = 0; x < width; ++x)
- {
- result = addrgb_tree(h, p->table[*chunky++], 1);
- if (result != ADDH_SUCCESS) goto fail;
- }
-
- if (proghook)
- {
- progmsg.RND_PMsg_count = y;
- if (!CallHookPkt(proghook, h, &progmsg))
- {
- result = ADDH_CALLBACK_ABORTED;
- goto fail;
- }
- }
-
- chunky += totw - width;
- }
- fail:
- ReleaseSemaphore(&h->lock);
- }
- return result;
- }
-
-
- /**************************************************************************
- **
- ** createhistogrampointerarray
- */
-
- static struct RNDHistoEntry **scantree(struct RNDTreeNode *node, struct RNDHistoEntry **destp)
- {
- if (node->left) destp = scantree(node->left, destp);
- if (node->right) destp = scantree(node->right, destp);
- *destp++ = &node->entry;
- return destp;
- }
-
- LIBAPI struct RNDHistoEntry **CreateHistogramPointerArray(RNDHISTO *h)
- {
- struct RNDHistoEntry **array = NULL;
- ULONG numcolors;
- ObtainSemaphoreShared(&h->lock);
- numcolors = QueryHistogram(h, RND_NumColors);
- if (numcolors > 0 && numcolors != 0xffffffff)
- {
- array = AllocRenderVec(h->rmh, numcolors * sizeof(struct RNDHistoEntry *));
- if (array)
- {
- scantree(h->root, array);
- }
- }
- ReleaseSemaphore(&h->lock);
- return array;
- }
-
-
- /**************************************************************************
- **
- ** countrgb
- */
-
- static ULONG findrgb_tree(RNDHISTO *h, ULONG rgb)
- {
- struct RNDTreeNode *node = h->root;
-
- ULONG rgbmask = h->rgbmask;
- ULONG chkmask = 0x800000;
-
- rgb &= rgbmask;
-
- while (node)
- {
- if (node->entry.rgb == rgb)
- {
- return (ULONG) node->entry.count;
- }
-
- while (!(chkmask & rgbmask)) chkmask >>= 1;
-
- if (rgb & chkmask)
- {
- node = node->left;
- }
- else
- {
- node = node->right;
- }
-
- chkmask >>= 1;
- }
-
- return 0;
- }
-
- LIBAPI ULONG CountRGB(RNDHISTO *h, ULONG rgb)
- {
- ULONG result;
- ObtainSemaphoreShared(&h->lock);
- result = findrgb_tree(h, rgb);
- ReleaseSemaphore(&h->lock);
- return result;
- }
-
-
- /**************************************************************************
- **
- ** counthistogram
- */
-
- LIBAPI ULONG CountHistogram(RNDHISTO *h)
- {
- return h->numcolors;
- }
-
-
- /**************************************************************************
- **
- ** addhistogram
- */
-
- static ULONG addtree(struct RNDTreeNode *node, RNDHISTO *dest, ULONG weight)
- {
- ULONG result = ADDH_SUCCESS;
-
- if (node->left)
- {
- result = addtree(node->left, dest, weight);
- }
-
- if (result == ADDH_SUCCESS)
- {
- if (node->right) result = addtree(node->right, dest, weight);
- }
-
- if (result == ADDH_SUCCESS)
- {
- result = addrgb_tree(dest, node->entry.rgb, node->entry.count * weight);
- }
-
- return result;
- }
-
- LIBAPI ULONG AddHistogramA(RNDHISTO *dst, RNDHISTO *src, struct TagItem *tags)
- {
- ULONG result = ADDH_NO_DATA;
- if (dst && src)
- {
- ULONG weight = GetTagData(RND_Weight, 1, tags);
- ObtainSemaphoreShared(&src->lock);
- ObtainSemaphore(&dst->lock);
- result = addtree(src->root, dst, weight);
- ReleaseSemaphore(&dst->lock);
- ReleaseSemaphore(&src->lock);
- }
- return result;
- }
-